package kmn.udpservice.service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import java.util.ArrayList;
import java.util.List;


import kmn.udpservice.data.AuthentificationData;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class UDPservice extends Service implements IUDPservice
{
	private IBinder binder = new UDPserviceBinder();
	private List<IUDPserviceListener> listeners = null;
	private InetAddress local = null;
	private DatagramSocket socket = null;
	private int port_server = 31455;
	
	public void onCreate() {
	    super.onCreate();
	    Log.d("UDPservice", "onCreate");
	    try
	    {
	    	socket = new DatagramSocket();
	    	socket.setSoTimeout(6000); // receive bloquant pendant 6 seconde au maximum
	    	local = InetAddress.getByName("192.168.1.75");
	    	Log.d(local.getHostName(), local.getHostAddress());
	    }
	    catch(SocketException e)
	    {
	    	Log.d("Socket", "Socket Exception");
	    }
	    catch(UnknownHostException e)
	    {
	    	Log.d("Socket", "Unknown host");
	    }
	}
	
	public int onStartCommand(Intent intent, int flags, int startId) 
	{  
		Log.d(this.getClass().getName(), "onStart");
		/*********ZONE DE TEST**********/
		AuthentificationData data = new AuthentificationData("clementDaboss", "1304xxxx");
		/*********FIN ZONE DE TEST**********/
		
		sendData(data);
		Object x = null;
		x = receiveData();
		
		fireDataChanged(x);
					
	    return START_NOT_STICKY;
	}

	public void onDestroy() 
	{
	    Log.d(this.getClass().getName(), "onDestroy");
	    socket.close();
	}
	
	public int sendData(Object tosend)
	{	
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		try
		{
			ObjectOutputStream oos = new ObjectOutputStream(output);
			try
			{
				oos.writeObject(tosend);
			}
			catch (IOException e)
			{
				oos.close();
				output.close();
			}
		}	
		catch (IOException e)
		{
			Toast.makeText(getApplicationContext(), "Erreur lors de l'ecriture des données", Toast.LENGTH_SHORT).show();
			return -1;
		}
		
		DatagramPacket p = new DatagramPacket(output.toByteArray(), output.toByteArray().length, local, port_server);
		try
		{		
			socket.send(p);
		}
		catch(IOException e)
		{
			Toast.makeText(getApplicationContext(), "Erreur lors de l'envoie des données au serveur", Toast.LENGTH_SHORT).show();
			return -1;
		}
		return 0;
	}
	
	public Object receiveData()
	{
		byte[] buffer = new byte[1024];
		DatagramPacket p = new DatagramPacket(buffer, buffer.length);
		try
		{
			socket.receive(p);
		}
		catch(IOException e)
		{
			Toast.makeText(getApplicationContext(), "Serveur injoignable", Toast.LENGTH_SHORT).show();
			return null;
		}
		
		ByteArrayInputStream input = new ByteArrayInputStream(buffer);
		try
		{
			ObjectInputStream oos = new ObjectInputStream(input);
			try
			{
				return oos.readObject();
			}
			catch (IOException e)
			{
				return null;
			}
			catch(ClassNotFoundException e) 
			{
				return null;
			}
			finally
			{
				oos.close();
				input.close();
			}
		}
		catch(IOException e)
		{
			Toast.makeText(getApplicationContext(), "Serveur injoignable", Toast.LENGTH_SHORT).show();
			return null;
		}		
	}
	
    
	@Override
	public IBinder onBind(Intent intent) 
	{
		Log.d("UDPservice", "onBind");
		return binder;
	}

	@Override
	public void addListener(IUDPserviceListener listener) 
	{

		if(listeners == null){
	        listeners = new ArrayList<IUDPserviceListener>();
	    }
	    listeners.add(listener); 
	    Log.d("Service", "Listener Added");
	}

	@Override
	public void removeListener(IUDPserviceListener listener) {
		if(listeners != null){
	        listeners.remove(listener);
	    } 
	}
	
    private void fireDataChanged(Object data){  
        if(listeners != null){  
            for(IUDPserviceListener listener: listeners){  
                listener.dataChanged(data);  
            }  
        }  
    } 

    public class UDPserviceBinder extends Binder
    {
    	public UDPservice getService() {
            return UDPservice.this;
        }
    }
}



